package com.crm.controller.invoiceController;

import java.io.ByteArrayOutputStream;

import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRBeanArrayDataSource;
import net.sf.jasperreports.engine.export.ooxml.JRDocxExporter;
import net.sf.jasperreports.engine.export.ooxml.JRDocxExporterParameter;
import net.sf.jasperreports.engine.util.JRLoader;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.crm.beans.SupplyParts;
import com.crm.dao.AttachmentHistoryDAO;
import com.crm.dao.ClientdetDAO;
import com.crm.dao.InvoiceStatusDAO;
import com.crm.dao.OpportunityDAO;
import com.crm.dao.PartsDAO;
import com.crm.dao.QuotationDAO;
import com.crm.dao.SupplyOrderDAO;
import com.crm.entity.AttachmentHistory;
import com.crm.entity.Business;
import com.crm.entity.Clientdet;
import com.crm.entity.InvoiceStatus;
import com.crm.entity.Opportunity;
import com.crm.entity.Parts;
import com.crm.entity.Quotation;
import com.crm.entity.SupplyOrder;
import com.crm.entity.User;
import com.crm.util.Constants;
import com.crm.util.NumToWords;

@Controller
@RequestMapping("/invoice")
public class InvoiceController {
	protected final Log logger = LogFactory.getLog(getClass());
	//OpportunityDAO opportunityDAO=new OpportunityDAO();
	AttachmentHistoryDAO attachmentDAO=new AttachmentHistoryDAO();
	PartsDAO partsDAO=new PartsDAO();
	SupplyOrderDAO supplyOrderDAO=new SupplyOrderDAO();
	QuotationDAO quotationDAO=new QuotationDAO();
	ClientdetDAO clientdetDAO=new ClientdetDAO();
	
	
	@RequestMapping("/show.do")
	public ModelAndView show(HttpServletRequest request,HttpSession session,HttpServletResponse response,ModelAndView model) throws Exception{
		Business bus=(Business)session.getAttribute("business");
		if(bus==null)return new ModelAndView("/jsp/index.jsp");
		int busid=bus.getBusinessId();
		
		
		String status=Constants.ST_GENERATED_SUP_INVOICE;
		
		List<Opportunity> lopp=OpportunityDAO.getSingleInstance().getByStatus(status, busid);
		model=new ModelAndView("/jsp/invoice.jsp");
		model.addObject("menuName","invoice");
		model.addObject("submenu","invoice");
		model.addObject("opportunityList",lopp);
		return model;
	}
	@RequestMapping( "/printinvoice.do") 
	public ModelAndView printpi(HttpServletRequest req,HttpSession session, ModelAndView model) throws Exception{
		Business bus=(Business)session.getAttribute("business");
		if(bus==null)return new ModelAndView("/jsp/index.jsp");
			
			List<AttachmentHistory> attlist=null;
			try{attlist=attachmentDAO.getAllPi(bus.getBusinessId(),"INVOICE");
					logger.info("attachment list is "+attlist);
			}catch(NullPointerException e){
				e.printStackTrace();
			}
			  model = new ModelAndView("/jsp/printInvoice.jsp");
				model.addObject("attlist",attlist);
				model.addObject("submenu", "invoice");
				model.addObject("menuName","invoice");
				 
		 
				return model;
	}
	
	
	@RequestMapping(value = "/get_invoice.do", method = RequestMethod.GET)
	public String pinting(HttpSession session, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		Business bus = (Business) session.getAttribute("business");

		String idno = request.getParameter("quotid");
		int id=Integer.parseInt(idno);
		AttachmentHistory att = attachmentDAO.getAttachmentHistoryByPI(id);
		logger.info("the business id is  " + bus.getBusinessId());
		byte[] pdfReport = att.getFileBlob();
		logger.info("the length of pdf is" + pdfReport.length);
		logger.info("the length of pdf is" + pdfReport.toString());
		ServletOutputStream servletOutputStream = response.getOutputStream();
		String fileName = "quotation.doc";
		response.setHeader("Content-Disposition", "inline; filename=" + fileName);
		response.setContentLength(pdfReport.length);
		servletOutputStream.write(pdfReport);
		servletOutputStream.flush();
		servletOutputStream.close();
		return null;

	}
	@RequestMapping("/setInvoice.do")
	public ModelAndView setInvoice(HttpServletRequest request,HttpSession session,HttpServletResponse response,ModelAndView model) throws Exception{
		Business bus=(Business)session.getAttribute("business");
		if(bus==null)return new ModelAndView("/jsp/index.jsp");
		
		int busid=bus.getBusinessId();
		
		String refNo=request.getParameter("refNo");
		
		Opportunity o=OpportunityDAO.getSingleInstance().getByRefNo(bus.getBusinessId(),refNo);
		int rfnum=o.getId();
		String quotNo=request.getParameter("quotNo");
		
		Quotation quot=quotationDAO.getByQuotid(quotNo);
		System.out.println("Quotation Id Is:"+quot.getId());
		List<SupplyOrder> lso=supplyOrderDAO.getByQuotid(bus.getBusinessId(),quot.getId());
		List<SupplyParts> lsp=new ArrayList<SupplyParts>();
		//String invoice=null;
		String cmpName=bus.getShortname();
		String custName=o.getClientId().getOrganisation();
		ClientdetDAO clDAO=new ClientdetDAO();
		
		
		Clientdet cN=clDAO.getCliOrg(bus.getBusinessId(),custName);
		String cNam=cN.getShrtname();
		String enqType=o.getEnquirytype();
		SupplyOrderDAO supDAO=new SupplyOrderDAO();
		
		Long c=supDAO.getCount(bus.getBusinessId());

		DateFormat formatter1 =Constants.DD_MM_YYYY;
		Date date1 = Constants.cal.getTime();
		String dt= formatter1.format(date1);
		
		String invNo=cmpName+"/"+cNam+"/"+enqType+"/"+c+"/"+dt;
		
  	  String soNo=null;
  	  Date date=null;
  	 System.out.println("Size Of SUpply Order Is:"+lso.size());
		if (lso!=null) {
			Iterator<SupplyOrder> itr=lso.iterator();
			while (itr.hasNext()==true) {
				SupplyOrder so = (SupplyOrder) itr.next();
				
				int partId = Integer.parseInt(""+so.getPrtid());
				logger.info("Part Id Is:"+partId);
				Parts part = partsDAO.findById(partId, busid,rfnum);
				
				SupplyParts sup = new SupplyParts(""+part.getDescription(),so.getPrice()+"",part.getQty()+"",part.getMake(),part.getPrtnum(),so.getPrc_aftr_discount() + "");
				
				//invoice = so.getInvoice();
				soNo = so.getSuplyOrderNum();
				date = so.getDate();
				lsp.add(sup);
				System.out.println("List in Loop Is :" + lsp);
			}
		}
		logger.info("Supply Order List Is:"+lsp);
		logger.info("SO NO Is:"+soNo);	
		
		SimpleDateFormat sdf=new SimpleDateFormat("dd-MM-yyyy");
		String da=sdf.format(date);
		System.out.println("Date Is:"+da);
		return model=new ModelAndView("/jsp/invoiceRes.jsp")
		.addObject("menuName","invoice")
		.addObject("submenu","invoice")
		.addObject("invoiceNo",invNo)
		.addObject("soNo",soNo)
		.addObject("Date",da)
		.addObject("clientdet",o.getOrganisation())
		.addObject("division",o.getDivision())
		.addObject("user",o.getUser())
		.addObject("soParts",lsp).addObject("terms",bus.getTandc());
	}
	@RequestMapping("/quotSearch.do")
	public @ResponseBody String quotSearch(HttpServletRequest request,HttpSession session,HttpServletResponse response,ModelAndView model) throws Exception{
		
		Business bus=(Business)session.getAttribute("business");
		String refNo=request.getParameter("refNo");
		int busid=bus.getBusinessId();

		int enqid=OpportunityDAO.getSingleInstance().getByRef(refNo, busid).getId();
		StringBuilder sb=new StringBuilder();
		
		
		
		List<Quotation> lQuot=quotationDAO.getQuotByEnq(enqid,bus.getBusinessId());
		Iterator<Quotation> itr=lQuot.iterator();
		while(itr.hasNext()==true){
			Quotation q=(Quotation)itr.next();
			sb.append(q.getQuotno()+",");
		}
		return sb.toString();
	}
	@RequestMapping("/genInvoice.do")
	public ModelAndView genInvoice(HttpServletRequest request,HttpSession session,HttpServletResponse response,ModelAndView model) throws Exception{
		
		Business bus=(Business)session.getAttribute("business");
		User user=(User)session.getAttribute("user");
		String refNo=request.getParameter("refNo");
	
		int busid=bus.getBusinessId();
		
		
		
		Opportunity op=OpportunityDAO.getSingleInstance().getByRef(refNo, busid);
		 String enqtype=op.getEnquirytype();
		
		String comp=bus.getBusinessName();
		
		String tinNo=bus.getTinno();
		String cstNo=bus.getCstno();
		String panNo=bus.getPanno();
		long lmicr=bus.getMicr();
		String micr=Long.toString(lmicr);
		String ifsc=bus.getIfsc();
		long laccno=bus.getAccno();
		String accno=Long.toString(laccno);
		String client=op.getOrganisation();
		
		String invc=request.getParameter("invoiceNo");
		String soDate=request.getParameter("soDate");
		String soDueDate=request.getParameter("sodueDate");
		String spONum=request.getParameter("soNo");
		String srowCount=request.getParameter("rowCount");
		String terms=request.getParameter("terms");
		int rowCount=Integer.parseInt(srowCount);
		logger.info("Row Count Is:"+rowCount);
		
		
		Map<String,String> parms = new HashMap<String,String>();
		List<com.crm.beans.SupplyParts> lst=new ArrayList<com.crm.beans.SupplyParts>();
		float total=0;
		float subtotal=0;
		float vt=0;
		for(int i=0;i<rowCount;i++){
			String prtnum=request.getParameter("partNumber"+(i+1));
			logger.info("Part Number Is:"+prtnum);
			
			String descript=request.getParameter("description"+(i+1));
			String make=request.getParameter("make"+(i+1));
			String qty= request.getParameter("qty"+(i+1));
			
			int intQty=Integer.parseInt(qty);
			
			Object utprice=request.getParameter("unitPrice"+(i+1));
			float untprice=getFloatVal(i, utprice);
			
			Object obsubtot=request.getParameter("subTot"+(i+1));
			float subtot=getFloatVal(i, obsubtot);
			
			
			float cost=intQty*untprice;
			subtotal=subtotal+cost;
			
			total=total+subtot;
			vt=(total*5)/100;
			com.crm.beans.SupplyParts qp=null;
			String sno=request.getParameter("sno"+(i+1));
			if(descript!=null){
			 qp=new com.crm.beans.SupplyParts(prtnum,descript,make+"",qty,utprice.toString(),Float.toString(subtot) , sno);
			}
			else{
				qp=new com.crm.beans.SupplyParts(prtnum,"",make+"",qty,utprice.toString(),Float.toString(subtot) , sno);
			}
			lst.add(qp);
		}
		Opportunity opp=OpportunityDAO.getSingleInstance().getByRefNo(busid,refNo);
		
		 Object ob;
		 Clientdet cl = null;
		 try {
			ob=clientdetDAO.getClient(busid,client);
			cl=(Clientdet)ob;
		} catch (Exception e1) {
			
			e1.printStackTrace();
		}
		String head=null; 
		if(enqtype.trim().equalsIgnoreCase("CP")){
			head="CASH BILL";
		}else
		{
			head="INVOICE";
		}
		int totprice=(int)(total+vt);
		// Adding invoiceNumber,date and DueDate;
				InvoiceStatus s=new InvoiceStatus();
				InvoiceStatusDAO invDAO=new InvoiceStatusDAO();
				s.setInvoicenumber(invc);
				s.setBusinessId(bus);
				Date soDate1=null;
				Date soDueDate1=null;
				DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
				 soDate1 = formatter.parse(soDate);
				 soDueDate1=formatter.parse(soDueDate);
				s.setSoDate(soDate1);
				s.setSoDueDate(soDueDate1);
				s.setStatus("open");
				s.setAmount(totprice);
				invDAO.insert(s);
				
				
		
		NumToWords numto= new NumToWords();
		String priceword=numto.convert(totprice);
		parms.put("htitle",head);
		 parms.put("sodate", soDate);
		 parms.put("customer",client);
		 parms.put("custaddr", cl.getAddr());
	     parms.put("date",soDate);
		 parms.put("total",totprice+"");
		 parms.put("vat",vt+"");
		 parms.put("subtotal",Math.round(subtotal)+"");
		 parms.put("from",comp );
		 parms.put("terms", terms);
		 parms.put("priceword", "Total (In Words)"+priceword+" "+opp.getCurencytype()+ "  Only  ");
		 parms.put("manager", user.getUserName()+"\n Operations Manager.");
		 parms.put("invoiceno",invc);
		 parms.put("tinno",tinNo);
		 parms.put("cstno", cstNo);
		 parms.put("panno", panNo);
		 parms.put("sonumber", spONum);
		 parms.put("micrno", micr);
		 parms.put("ifsccode", ifsc);
		 parms.put("sbiacno", accno);
		 
		 JasperReport report = (JasperReport) JRLoader.loadObject(session.getServletContext().getResourceAsStream("/WEB-INF/classes/reports/Invoice.jasper"));
		JasperPrint prt = JasperFillManager.fillReport(report,parms,new JRBeanArrayDataSource(lst.toArray()));
		byte[] pdfReport = JasperExportManager.exportReportToPdf(prt);
		
		
		JRDocxExporter docExporter=new JRDocxExporter();
		ByteArrayOutputStream docStream=new ByteArrayOutputStream();
		docExporter.setParameter(JRDocxExporterParameter.JASPER_PRINT,prt);
		docExporter.setParameter(JRDocxExporterParameter.OUTPUT_STREAM,docStream);
		docExporter.setParameter(JRDocxExporterParameter.FLEXIBLE_ROW_HEIGHT, Boolean.TRUE);
		docExporter.exportReport();
		pdfReport = docStream.toByteArray();
		
		AttachmentHistory attachment=new AttachmentHistory("application/msword",bus,Constants.INVOICE,pdfReport,op.getRefNum(),invc,new java.util.Date());
		
		
		String status=Constants.ST_GENERATED_INVOICE;
		
		int rid=opp.getId();
		try {
			OpportunityDAO.getSingleInstance().updateStatus(busid,status,rid);
			attachmentDAO.insert(attachment);
			System.out.println("Sucessfully Generated Invoice");
		}catch(Exception e){
			e.printStackTrace();
			System.out.println("Failed To Generate Invoice");
		}
		
		model=new ModelAndView("/jsp/InvoicePDF.jsp");
		model.addObject("invoiceno",invc);
		model.addObject("refno",op.getRefNum());
		model.addObject("resmsg","Sucesssfully Created Invoice  With Number"+op.getRefNum());
		model.addObject("menuName","invoice");
		model.addObject("submenu","invoice");
	
		return model;
	}
	private float getFloatVal( int selrow, Object obunitval){
		float unitval=0;
	if(obunitval instanceof Float) {
		 unitval=(Float)obunitval;
	 }else{
		
		String sunitval=obunitval.toString();
		try {
			unitval=Float.parseFloat(sunitval);
		} catch (NumberFormatException e) {
			logger.info("Invalid data at row,col  val "+selrow+","+5+" = sunitval");
			e.printStackTrace();
		}
	 }
	return unitval;
}
	
	
	@RequestMapping("/get_history.do")
	public String htmlReport(HttpSession session,HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		Business bus=(Business)session.getAttribute("business");

		String quotno=request.getParameter("quotid");
		
		
		
		AttachmentHistory att=attachmentDAO.getAttachmentHistoryByInvoice(bus.getBusinessId(),Constants.INVOICE,quotno.trim());
		logger.info("the quotation no is "+quotno.trim());
		logger.info("the business id is  "+bus.getBusinessId());
		byte[] pdfReport =att.getFileBlob();
		logger.info("the length of pdf is"+pdfReport.length);
		logger.info("the length of pdf is"+pdfReport.toString());
		ServletOutputStream servletOutputStream = response.getOutputStream();
		response.setContentType("application/msword");
		response.setContentLength(pdfReport.length);
		servletOutputStream.write(pdfReport);
		servletOutputStream.flush();
		servletOutputStream.close(); 
		return null;
	   
	}

}
